package com.fand.common.util;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.LFUCache;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.fand.common.exception.BusinessException;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * ip工具类
 * <p>
 * Author: zhangjiabin
 * Email: javaboyok@163.com
 * CreateDate: 2021/6/26
 * Version: 1.0
 */
@Slf4j
public class IPUtil {

    private static final String CACHE_KEY = "fand-cache-";

    private static LFUCache<String, String> lfuCache = CacheUtil.newLFUCache(10000, 30 * 60 * 1000);


    private static final String BASE_URL = "https://apis.map.qq.com";

    /**
     * 腾讯应用key
     */
    private static final String TENCENT_KEY = "EBHBZ-G37KV-YSPPK-U36HD-FHERS-FTFBA";

    /**
     * 腾讯应用key 的sec
     */
    private static final String TENCENT_SECRET_KEY = "Cgs92X22VRQxfHONXYL7BzKFZXWojXx";

    /**
     * 根据ip获取地址,调用腾讯的地图服务
     * 帮助文档：https://lbs.qq.com/service/webService/webServiceGuide/webServiceIp
     */
    public static String ip2Address(String ip) {
        if (StrUtil.isEmpty(ip)) {
            throw new BusinessException("非法参数");
        }
        log.info("IPUtil ip2Address ip为：{}", ip);

        String result = lfuCache.get(CACHE_KEY + ip);
        if (StrUtil.isNotEmpty(result)) {
            return result;
        }
        /**
         * 1、需要对请求参数进行md5签名
         */
        StrBuilder strBuilder = StrBuilder.create();
        strBuilder.append("/ws/location/v1/ip");
        strBuilder.append("?ip=" + ip);
        strBuilder.append("&key=" + TENCENT_KEY);

        String sig = SecureUtil.md5(strBuilder.toString() + TENCENT_SECRET_KEY);

        strBuilder.append("&sig=" + sig);
        log.info("请求路径为：{}", BASE_URL + strBuilder.toString());
        String resultJson = HttpClientUtil.doGet(BASE_URL + strBuilder.toString());
        log.info("返回结果为：{}", resultJson);
        /*{
            "status": 0,
                "message": "query ok",
                "result": {
            "ip": "117.80.114.220",
                    "location": {
                "lat": 31.29834,
                        "lng": 120.58319
            },
            "ad_info": {
                "nation": "中国",
                        "province": "江苏省",
                        "city": "苏州市",
                        "district": "",
                        "adcode": 320500
            }
        }
        }*/

        Address address = JsonUtils.jsonToPojo(resultJson, Address.class);
        if (address.getStatus() == 0) {
            Address.ResultBean.AdInfoBean adInfo = address.getResult().getAd_info();
            String nation = adInfo.getNation();//国
            String province = adInfo.getProvince();//省
            String city = adInfo.getCity();//地级市
            String district = adInfo.getDistrict() == "" ? "" : "-" + adInfo.getDistrict();//区
            String addressStr = nation + "-" + province + "-" + city + district;
            lfuCache.put(CACHE_KEY + ip, addressStr);
            return addressStr;
        }
        lfuCache.put(CACHE_KEY + ip, "--");
        return "--";
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    private static class Address {
        private int        status;
        private String     message;
        private ResultBean result;

        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        @Builder
        private static class ResultBean {
            private String       ip;
            private LocationBean location;
            private AdInfoBean   ad_info;

            @Data
            @NoArgsConstructor
            @AllArgsConstructor
            @Builder
            private static class LocationBean {
                private double lat;
                private double lng;
            }

            @Data
            @NoArgsConstructor
            @AllArgsConstructor
            @Builder
            private static class AdInfoBean {

                private String nation;
                private String province;
                private String city;
                private String district;
                private int    adcode;
            }
        }
    }

    public static void main(String[] args) {
        String s = IPUtil.ip2Address("117.80.114.220");
        System.out.println(s);
    }

}
